package com.hoo.permission.sdk.server.dao.impl;

import com.hoo.common.model.Page;
import com.hoo.permission.sdk.server.dao.ISysResourceDao;
import com.hoo.permission.sdk.server.domain.entity.SysResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 系统-资源表(菜单、按钮) Dao层 实现
 * @author 小韩工作室
 * @date 2020-06-28 16:51:32
 */
@Repository
public class SysResourceDaoImpl implements ISysResourceDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public boolean add(SysResource entity){
        if(entity.getParentId() == null || entity.getParentId() < 0) {
            entity.setParentId(0L);
        }
        KeyHolder keyHolder = new GeneratedKeyHolder();
        PreparedStatementCreator preparedStatementCreator = con -> {
            PreparedStatement ps = con.prepareStatement("INSERT INTO t_sys_resource(parent_id, name, icon, url, path, permission, sort, hide, type, status) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
            ps.setLong(1, entity.getParentId());
            ps.setString(2, entity.getName());
            ps.setString(3, entity.getIcon());
            ps.setString(4, entity.getUrl());
            ps.setString(5, entity.getPath());
            ps.setString(6, entity.getPermission());
            ps.setInt(7, entity.getSort());
            ps.setBoolean(8, entity.isHide());
            ps.setInt(9, entity.getType());
            ps.setString(10, entity.getStatus());
            return ps;
        };

        if(jdbcTemplate.update(preparedStatementCreator, keyHolder) > 0) {
            entity.setId(keyHolder.getKey().longValue());
            return true;
        }
        return false;
        // return jdbcTemplate.update("INSERT INTO t_sys_resource(id, parent_id, name, icon, url, path, permission, sort, hide) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)", entity.getId(), entity.getParentId(), entity.getName(), entity.getIcon(), entity.getUrl(), entity.getPath(), entity.getPermission(), entity.getSort(), entity.isHide()) > 0;
    }

    @Override
    public boolean update(SysResource entity) {
        if(entity.getParentId() == null || entity.getParentId() < 0) {
            entity.setParentId(0L);
        }
        return jdbcTemplate.update("UPDATE t_sys_resource SET parent_id = ? ,name = ? ,icon = ? ,url = ? ,path = ? ,permission = ? ,sort = ? ,hide=?, type=?,status=?  WHERE id = ?",
                entity.getParentId(), entity.getName(), entity.getIcon(), entity.getUrl(), entity.getPath(), entity.getPermission(), entity.getSort(), entity.isHide(), entity.getType(), entity.getStatus(), entity.getId()) > 0;
    }

    @Override
    public boolean delete(SysResource entity){
        return jdbcTemplate.update("DELETE FROM t_sys_resource WHERE id = ?", entity.getId()) > 0;
    }

    @Override
    public boolean delete(Serializable id){
        SysResource entity = new SysResource();
        entity.setId((Long)id);
        return delete(entity);
    }

    @Override
    public boolean batchDelete(List<Long> ids) {
        List<Object[]> list = new ArrayList<>();
        if (ids != null && ids.size() > 0) {
            for (Long id : ids) {
                list.add(new Long[] {id});
            }
            return jdbcTemplate.batchUpdate("DELETE FROM t_sys_resource WHERE id = ?", list).length == ids.size();
        }
        return false;
    }

    @Override
    public boolean deleteByParentId(Long parentId) {
        // 子节点深层次嵌套
        List<Long> childIds = jdbcTemplate.query("SELECT id FROM t_sys_resource WHERE parent_id = ?", new Object[] {parentId}, new BeanPropertyRowMapper<Long>(Long.class));
        List<Object[]> batchChildIds = new ArrayList<>();
        for(Long childId : childIds) {
            batchChildIds.add(new Object[] {childId});
        }
        jdbcTemplate.batchUpdate("DELETE FROM t_sys_resource WHERE id = ?", batchChildIds);
        for(Long childId : childIds) {
            this.deleteByParentId(childId);
        }
        return true;
    }

    @Override
    public SysResource get(Serializable id) {
        List<SysResource> list = jdbcTemplate.query("SELECT id, parent_id as parentId, name, icon, url, path, permission, sort, type, status FROM t_sys_resource WHERE id = ? ", new Object[]{ id }, new BeanPropertyRowMapper<SysResource>(SysResource.class));
        if(list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public List<SysResource> findAll(Map< String, Object> params) {
        List<Object> whereValues = new ArrayList<>();
        StringBuilder sql = new StringBuilder("SELECT id, parent_id as parentId, name, icon, url, path, permission, sort, type, status FROM t_sys_resource WHERE 1=1 ");
        if(params.get("status") != null) {
            sql.append("AND status = ? ");
            whereValues.add(params.get("status"));
        }
        if(params.get("parentId") != null) {
            sql.append("AND parent_id = ? ");
            whereValues.add(params.get("parentId"));
        }
        if(params.get("type") != null) {
            sql.append("AND type = ?");
            whereValues.add(params.get("type"));
        }
        if(params.get("userId") != null) {
            // 查询指定 用户的 资源权限
            StringBuilder childSql = new StringBuilder("SELECT m.id FROM t_sys_role_user ur " +
                    " LEFT JOIN t_sys_role_resource rm on ur.role_id = rm.role_id " +
                    " LEFT JOIN t_sys_resource m ON rm.resource_id = m.id " +
                    " WHERE ur.user_id = ?");
            childSql.append(" UNION ALL")
                    .append(" SELECT resource_id FROM t_sys_user_resource WHERE user_id = ?");
            sql.append(" AND id IN(").append(childSql).append(")");
            whereValues.add(params.get("userId"));
            whereValues.add(params.get("userId"));
        }
        if(params.get("searchWord") != null) {
            sql.append(" AND name LIKE ?");
            whereValues.add("%" + params.get("searchWord") + "%");
        }

        List<SysResource> list = jdbcTemplate.query(sql.append(" order by sort").toString(), whereValues.toArray(new Object[]{}), new BeanPropertyRowMapper<SysResource>(SysResource.class));
        if(list != null && list.size() > 0) {
            return list;
        }else{
            return new ArrayList<>();
        }
    }

    @Override
    public Page<SysResource> query(Page page, Map<String, Object> params) {
        if(page == null) {
            page = new Page();
        }
        Long total = jdbcTemplate.queryForObject("SELECT COUNT(1) FROM t_sys_resource WHERE 1=1 ", Long.class);
        List<SysResource> list = jdbcTemplate.query("SELECT id, parent_id as parentId, name, icon, url, path, permission, sort, type,status FROM t_sys_resource WHERE 1=1 LIMIT ?,?", new Object[]{(page.getPageNo() - 1) * page.getLimit(), page.getLimit()}, new BeanPropertyRowMapper<SysResource>(SysResource.class));
        if(list != null && list.size() > 0) {
            page.setRecords(list);
        }
        page.setTotal(total);
        return page;
    }
}
